package methodhandler;

import com.IPepole;
import com.Student;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

/**
 * 验证 methodhandler 类的使用
 */
public class MethodHandlerMain {

    private String hello(String name) {
        System.out.println("hello " + name);
        return name;
    }


    public static void main(String[] args) {

        try {
            //反射无参构造方法构建对象
            MethodType constructorParamType = MethodType.methodType(void.class);
            MethodHandle constructor = MethodHandles.lookup().findConstructor(Student.class, constructorParamType);
            Student s = (Student) constructor.invokeExact();
//            s.learn("123");
            System.out.println("反射构造方法构建student对象" + s);


            //反射public 修饰的方法
            MethodType learnParam = MethodType.methodType(String.class, int.class);
            MethodHandle learnHandle = MethodHandles.lookup().findVirtual(Student.class, "learn", learnParam);
            Student s2 = new Student();
            String result = (String) learnHandle.invokeExact(s2, 66);
            System.out.println(result);

            //反射public 修饰的方法
            MethodType moveMethodType = MethodType.methodType(void.class, String.class);
            MethodHandle moveHandle = MethodHandles.lookup().findVirtual(Student.class, "movie", moveMethodType);
            Student s3 = new Student();
            moveHandle.invokeExact(s2, "ererr");


            /**
             *  反射private 修饰的方法
             *  该方式只能访问到当前类的私有方法
             */
            MethodType sayMethodType = MethodType.methodType(String.class, String.class);
            MethodHandle sayHandle = MethodHandles.lookup().findSpecial(MethodHandlerMain.class, "hello",
                    sayMethodType, MethodHandlerMain.class);
            MethodHandlerMain mhm = new MethodHandlerMain();
            String sayresult = (String) sayHandle.invokeExact(mhm, "hello method");
            System.out.println(sayresult);


            /**
             *  反射静态 修饰的方法
             *  要求:该方式只能访问到当前类的私有方法
             */
            MethodType staticMethodType = MethodType.methodType(void.class);
            MethodHandle staticHandle = MethodHandles.lookup().findStatic(Student.class, "pao",
                    staticMethodType);
            staticHandle.invokeExact();

            /**
             * 获取set方法
             * 要求: 必须要严格遵守类的访问规则
             */
            MethodHandle setHandle = MethodHandles.lookup().findSetter(Student.class, "name",
                    String.class);
            Student stu1 = new Student();
            setHandle.invokeExact(stu1, "设置名字");
            System.out.println("反射set方法:" + stu1.getName());


        } catch (Throwable e) {
            e.printStackTrace();
        }

    }


}
